const app = angular.module("myApp",['ui.bootstrap','ui.bootstrap.datetimepicker']);

app.controller("diagnosisController",['$scope','$window','$interval',function($scope,$window,$interval){
    $scope.toJSON = function (val) {
        return toJSON(val);
    };

    $scope.inCheckList = function (signal) {
        return $scope.faultMatched.filter(fault=>fault!=null && fault.checked).some(fault=>fault.channels.some(channel=>channel.id==signal.portId));
    };

    $scope.withUnknown = function (fault) {
        return fault!=null && (fault.isMatched || $scope.showUnknown && fault.isUnknown);
    };

    $scope.timeClick = function ($event) {
        $event.preventDefault();
        $event.stopPropagation();
    };

    $scope.timeChanged = function ($event) {
        console.info($event.target);
    };

    $scope.toTimestamp = function () {
        $scope.dt.setTime($scope.t_timestamp);

        refreshSignals();
    };

    $scope.onTimeSet = function (newDate, oldDate) {
        $scope.status.isopen = !$scope.status.isopen;
        $scope.t_timestamp = $scope.dt.getTime();

        refreshSignals();
    };

    function refreshSignals() {
        $.get('http://'+window.location.hostname+':'+window.basePort+'/rest/work/last/signal/'+$scope.dt.getTime(),function (data) {
            $scope.signals = data;
            $scope.$apply();
        });
    }

    $scope.status = {
        isopen: false
    };

    $scope.dt = new Date();
    $scope.isCollapsed2 = false;
    $scope.showUnknown = false;
    $scope.faultCheck = {};
    $scope.faultMatched=[];

    $scope.$watch('isCollapsed2',function () {
        $scope.diagnoiseAgain();
    },true);

    $scope.diagnoiseAgain = function () {
        refreshSignals();
        $.post('http://'+window.location.hostname+':'+window.basePort+'/rest/work/kg/match/'+$scope.dt.getTime(),
            {
                content:JSON.stringify($scope.manmalSignals)
            },
            function (data) {
                $scope.matchedResult = data;
                let lastCheck = {};
                $scope.faultMatched.forEach(f=>{
                    lastCheck[f.id] = f.checked;
                });
                $scope.faultMatched = data.map(f=>{
                    f.checked = lastCheck[f.id] || false;
                    return f;
                });
                $scope.$apply();
            });
    };

    function showToReport(faultId,filename,title) {
        let result = $scope.matchedResult.filter(res=>res.id==faultId)[0];
        let matchedNodes,unknownNodes,channels;
        if(result!=null)
            matchedNodes = angular.toJson(result["matched"],false);
        else
            matchedNodes = "[]";

        if(result!=null)
            unknownNodes = angular.toJson(result["unknown"],false);
        else
            unknownNodes = "[]";

        if(result!=null){
            let channelList = result["channels"].map(ch=>{
                let value = _.find($scope.signals,port=>port.portId==ch.id).value;
                ch.value = value;
                return ch;
            });

            $scope.manmalSignals.filter(s=>s.faultName==result.faultName).forEach(signal=>{
                channelList.push({
                    name:signal.type=="manual"
                        ?("(人工)"+signal.description)
                        :`(${signal.component==null?"机组":signal.component.name})`+signal.featureType,
                    value:JSON.parse(signal.value)
                });
            });
            channels = angular.toJson(channelList,false);
        }else {
            channels = "[]";
        }

        let jumpTo = `${filename}?faultId=${faultId}&matchedNodes=${encodeURI(matchedNodes)}&unknownNodes=${encodeURI(unknownNodes)}&timestamp=${$scope.dt.getTime()}&last_timestamp=${result.last_timestamp}&channels=${encodeURI(channels)}`;
        if(isInFrame()){
            pushUrl(`../fault/${jumpTo}`,title);
        }else{
            $window.open(jumpTo);
        }
    }

    $scope.showFaultReport = function (faultId) {
        showToReport(faultId,"report.html","诊断报告");
    };

    $scope.showFaultTree = function (faultId) {
        showToReport(faultId,"FaultExplain.html","诊断解释");
    };

    $scope.manmalSignals = [];
    $scope.jumpToHuman = function (fid) {
        let result = $scope.matchedResult.filter(res=>res.id==fid)[0];
        if(result!=null){
            let unknownNodes = result["unknown"];

            function featureToID(isAuto,f,cp) {
                if(isAuto){
                    return "A&"+f.name+"&"+(cp==null?'NoC':cp.id);
                }else {
                    return "M"+f.id;
                }
            }

            function signalToID(s) {
                if(s.type=="manual"){
                    return "M"+s.id;
                }else {
                    return  "A&"+s.featureType+"&"+(s.component==null?'NoC':s.component.id);
                }
            }

            Graph.loadGraph(fid,g=>{
                let features = [... g.nodes.values()].filter(node=>node.$type=="Feature" && unknownNodes.some(uid=>uid==node.id));
                let fault = g.getRoot();
                let manS = new Map($scope.manmalSignals.map(s=>[signalToID(s),s]));
                features.forEach(f=>{
                    let isAuto = f.type.contains("auto");
                    let fx = FeatureNode.features.filter(feature=>feature.id == f.id);
                    let cp = null;
                    if(fx!=null && fx.length>0&&fx[0].components!=null&&fx[0].components.length!=0){
                        let id = fx[0].components[0];
                        let cx = [... g.nodes.values()].filter(c=>c.id==id);
                        if(cx!=null && cx.length>0){
                            cp={
                                id:id,
                                name:cx[0].name
                            }
                        }
                    }
                    manS.set(featureToID(isAuto,f,cp),{
                        id:f.id,
                        faultName:fault.name,
                        type:isAuto?"auto":"manual",
                        description:f.description,
                        featureType:f.name,
                        value:isAuto?"[0]":"unknown",
                        component:cp
                    });
                });
                $scope.manmalSignals = [...manS.values()];
                $scope.$apply();
            });
        }
        // alert("补充条件！！！");
    };

    $scope.deleteManualSignal = function (manualSignalId) {
        for(let i=0;i<$scope.manmalSignals.length;i++){
            let manalSignal = $scope.manmalSignals[i];
            if(manalSignal.id==manualSignalId){
                $scope.manmalSignals.splice(i,1);
                return;
            }
        }
    };

}]);

app.filter('startX', [function() {
    return function(array,size) {
        if(array.length<=size)
            return array.map(x=>x.toFixed(2)).join(",");
        return array.slice(0,2).map(x=>x.toFixed(2)).join(",")+"等"+array.length+"项";
    };
}]);

const toJSON = function (obj) {
    let cache = [];
    return JSON.stringify(obj, function(key, value) {
        if (typeof value === 'object' && value !== null) {
            if (cache.indexOf(value) !== -1) {
                // Circular reference found, discard key
                return;
            }
            // Store value in our collection
            cache.push(value);
        }
        return value;
    });
};

const isInFrame = function () {
  return localStorage.getItem("useInFrame")=="true";
};

const pushUrl = function (url,title) {
    let stackStr = localStorage.getItem("tabStack") || "[]";
    let stack = JSON.parse(stackStr);
    stack.push({
        url:url,
        title:title
    });
    stackStr = JSON.stringify(stack);
    localStorage.setItem("tabStack",stackStr);
};

FeatureNode.loadFeatures();